package cn.edu.cug.cs.gtl.docsrv.dict.dao;

import cn.edu.cug.cs.gtl.mybatis.mapper.dict.DictColInfo;
import cn.edu.cug.cs.gtl.mybatis.metadata.Constant;
import cn.edu.cug.cs.gtl.protos.TableInfo;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

public interface TableDao {
    List<Map> getTableStructureV1(String tableName) throws Exception;

    List<DictColInfo> getTableStructure(String tableName) throws Exception;

    TableInfo getTableInfo(String tableName) throws Exception;

    List<Map> getTableDataV1(String tableName, Integer pageNumber, Integer pageSize, List<Map> tableStructure) throws Exception;

    List<Map<String,Object>> getTableData(String tableName, Integer pageNumber, Integer pageSize, List<Map> tableStructure) throws Exception;

    Integer getTableDataCount(String tableName) throws Exception;

    void addTableData(String tableName, List<Map> columnList) throws Exception;

    void deleteTableData(String tableName, List<Map> columnList) throws Exception;

    void updateTableData(String tableName, List<Map> columnList) throws Exception;

    InputStream getTableBlobData(String tableName, String columnName, List<Map> columnList) throws Exception;

    //下面这些方法为默认方法，如果有需要变化可以在子类中重写
    default String buildSelectSQL(List<Map> columnList) throws Exception {
        return null;
    }

    default String buildInsertSQL(String tableName, List<Map> columnList) throws Exception {
        int index = 0;
        StringBuilder value = new StringBuilder(Constant.INSERT_TABLE_DATA).append(" ").append(tableName).append("(");
        for (Map map : columnList) {
            if (map.get("inputValue") != null) {
                value.append(map.get("columnName")).append(",");
                index++;
            }
        }

        if (index == 0) {
            throw new Exception("不能插入空数据，至少需要一个字段有值");
        }

        //删除最后一个,
        value.deleteCharAt(value.length() - 1).append(") VALUES (");
        for (int i = 0; i < index; i++) {
            value.append(" ?,");
        }
        value.deleteCharAt(value.length() - 1).append(")");
        return value.toString();
    }

    default String buildDeleteSQL(String tableName, List<Map> columnList) throws Exception {
        int index = 0;
        StringBuilder value = new StringBuilder(Constant.DELETE_TABLE_DATA).append(" ").append(tableName).append(" where ");
        for (Map map : columnList) {
            //BLOB无法作为判断条件，直接忽略
            if (!map.get("dataType").equals("BLOB")) {
                if (map.get("inputValue") != null) {
                    value.append(map.get("columnName")).append(" = '").append(map.get("inputValue")).append("' and ");
                } else {
                    value.append(map.get("columnName")).append(" is NULL and ");
                }
                index++;
            }
        }
        if (index == 0) {
            throw new Exception("无法删除只包含BLOB类型字段的表所包含的数据，无法区分数据");
        }

        return value.toString();
    }

    default String buildUpdateSQL(String tableName, List<Map> columnList) throws Exception {
        StringBuilder value = new StringBuilder(Constant.UPDATE_TABLE_DATA).append(" ").append(tableName);

        StringBuilder setValue = new StringBuilder(" set ");
        StringBuilder whereValue = new StringBuilder(" where ");

        int setIndex = 0;
        int whereIndex = 0;

        for (Map map : columnList) {
            //BLOB无法作为判断条件，直接忽略
            Object old = map.get("oldValue");
            Object input = map.get("inputValue");
            String columnName = (String) map.get("columnName");
            if (map.get("dataType").equals("BLOB")) {
                //BLOB类型不用来做判断条件
                if (old != null && input == null) {
                    //删除文件的情况
                    setValue.append(columnName).append(" = null, ");
                    setIndex++;
                } else if (input != null && !input.equals(old)) {
                    //表示新增了文件
                    setValue.append(columnName).append(" = ?, ");
                    setIndex++;
                }
                //还有就是文件没发生变化的情况，不处理
            } else {
                if (old != null) {
                    whereValue.append(columnName).append(" = '").append(old).append("' and ");
                } else {
                    whereValue.append(columnName).append(" is NULL and ");
                }
                whereIndex++;

                //数据被修改了，发生了变化
                if ((input != null || old != null) && (input == null || !input.equals(old))) {
                    setValue.append(columnName).append(" = ?, ");
                    setIndex++;
                }
            }
        }
        if (whereIndex == 0) {
            throw new Exception("无法更新只包含BLOB类型字段的表所包含的数据，无法区分数据");
        }
        if (setIndex == 0) {
            throw new Exception("至少需要更新一个字段");
        }

        setValue.delete(setValue.length() - 2, setValue.length());
        return value.append(setValue).append(whereValue).toString();
    }


}
